/*
 * ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.directory.http.client;


import java.net.Socket;
import java.util.Arrays;

import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.protocol.RequestUserAgent;
import org.apache.http.util.EntityUtils;


/**
 * Elemental example for executing a POST request.
 * <p>
 * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
 * It is NOT intended to demonstrate the most efficient way of building an HTTP client. 
 *
 *
 *
 */
public class ElementalHttpPost
{

    public static void main( String[] args ) throws Exception
    {

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion( params, HttpVersion.HTTP_1_1 );
        HttpProtocolParams.setContentCharset( params, "UTF-8" );
        HttpProtocolParams.setUserAgent( params, "HttpComponents/1.1" );
        HttpProtocolParams.setUseExpectContinue( params, true );

        BasicHttpProcessor httpproc = new BasicHttpProcessor();
        HttpRequestInterceptor[] interceptors = new HttpRequestInterceptor[]
            {
                // Required protocol interceptors
                new RequestContent(), new RequestTargetHost(),
                // Recommended protocol interceptors
                new RequestConnControl(), new RequestUserAgent(), new RequestExpectContinue() };
        httpproc.setInterceptors( Arrays.asList( interceptors ) );

        HttpRequestExecutor httpexecutor = new HttpRequestExecutor();

        HttpContext context = new BasicHttpContext( null );

        HttpHost host = new HttpHost( "localhost", 7009 );

        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
        ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();

        context.setAttribute( ExecutionContext.HTTP_CONNECTION, conn );
        context.setAttribute( ExecutionContext.HTTP_TARGET_HOST, host );

        try
        {

            HttpEntity[] requestBodies =
                { new StringEntity(
                    "{'name':'uid=admin,ou=system','credentials':'secret','isSimple':true,'version':3,'controls':{},'messageId':1}",
                    "UTF-8" ),
                //                    new ByteArrayEntity(
                //                            "This is the second test request".getBytes("UTF-8")),
                //                    new InputStreamEntity(
                //                            new ByteArrayInputStream(
                //                                    "This is the third test request (will be chunked)"
                //                                    .getBytes("UTF-8")), -1)
                };

            for ( int i = 0; i < requestBodies.length; i++ )
            {
                if ( !conn.isOpen() )
                {
                    Socket socket = new Socket( host.getHostName(), host.getPort() );
                    conn.bind( socket, params );
                }
                BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest( "POST",
                    "/adminapp/ldap/bind" );
                request.setEntity( requestBodies[i] );
                System.out.println( ">> Request URI: " + request.getRequestLine().getUri() );

                request.setParams( params );
                httpexecutor.preProcess( request, httpproc, context );
                HttpResponse response = httpexecutor.execute( request, conn, context );
                response.setParams( params );
                httpexecutor.postProcess( response, httpproc, context );

                System.out.println( "<< Response: " + response.getStatusLine() );
                System.out.println( EntityUtils.toString( response.getEntity() ) );
                System.out.println( "==============" );
                if ( !connStrategy.keepAlive( response, context ) )
                {
                    conn.close();
                }
                else
                {
                    System.out.println( "Connection kept alive..." );
                }
            }
        }
        finally
        {
            conn.close();
        }
    }

}
